package com.heima.wemedia.service.impl;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.green20220302.Client;
import com.aliyun.green20220302.models.*;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.teautil.models.RuntimeOptions;
import com.heima.wemedia.bean.ImageCheckResult;
import com.heima.wemedia.bean.TextCheckResult;
import com.heima.wemedia.config.AliYunGreenConfig;
import com.heima.wemedia.service.GreenTextService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
public class GreenTextServiceImpl implements GreenTextService {
    @Autowired
    private Client client;
    @Autowired
    private AliYunGreenConfig aliYunGreenConfig;
    public static Map<String, DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData> tokenMap = new HashMap<>();
    public static boolean isVPC = false;

    @Override
    public TextCheckResult textCheck(String text) {
        Map<String, Object> contentMap = MapUtil.<String, Object>builder().put("content", text).build();
        TextModerationPlusRequest textModerationPlusRequest = new TextModerationPlusRequest();
        // 检测类型
        textModerationPlusRequest.setService(this.aliYunGreenConfig.getTextService());
        textModerationPlusRequest.setServiceParameters(JSONUtil.toJsonStr(contentMap));
        try {
            TextModerationPlusResponse response = client.textModerationPlus(textModerationPlusRequest);
            if (response.getStatusCode() == 200) {
                TextModerationPlusResponseBody result = response.getBody();
                Integer code = result.getCode();
                if (200 == code) {
                    TextModerationPlusResponseBody.TextModerationPlusResponseBodyData data = result.getData();
                    System.out.println(JSON.toJSONString(data, true));

                    return TextCheckResult.builder()
                            .riskLevel(data.getRiskLevel())
                            .confidenceList(CollStreamUtil.toList(data.getResult(), TextModerationPlusResponseBody.TextModerationPlusResponseBodyDataResult::getConfidence))
                            .riskWordsList(CollStreamUtil.toList(data.getResult(), TextModerationPlusResponseBody.TextModerationPlusResponseBodyDataResult::getRiskWords))
                            .labelList(CollStreamUtil.toList(data.getResult(), TextModerationPlusResponseBody.TextModerationPlusResponseBodyDataResult::getLabel))
                            .build();
                }
            }
        } catch (Exception e) {
            log.error("文件检测失败！text = {}", text, e);
        }
        return TextCheckResult.builder().build();
    }

    @Override
    public ImageCheckResult imageCheck(String filePath) {
                       //获取文件上传token
        RuntimeOptions runtime = new RuntimeOptions();
        try {

            String bucketName = null;
            DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData uploadToken = tokenMap.get(this.aliYunGreenConfig.getEndpoint());
            //获取文件上传token
            if (uploadToken == null || uploadToken.expiration <= System.currentTimeMillis() / 1000) {
                DescribeUploadTokenResponse tokenResponse = client.describeUploadToken();
                uploadToken = tokenResponse.getBody().getData();
                bucketName = uploadToken.getBucketName();
            }
            //上传文件请求客户端
            OSS ossClient = getOssClient(uploadToken, isVPC);

            //上传文件
            //TODO
            String objectName = uploadFile(ossClient, filePath, uploadToken);

            // 检测参数构造。
            Map<String, String> serviceParameters = new HashMap<>();
            //文件上传信息
            serviceParameters.put("ossBucketName", bucketName);
            serviceParameters.put("ossObjectName", objectName);
            serviceParameters.put("dataId", UUID.randomUUID().toString());

            ImageModerationRequest request = new ImageModerationRequest();
            // 图片检测service：内容安全控制台图片增强版规则配置的serviceCode，示例：baselineCheck
            // 支持service请参考：https://help.aliyun.com/document_detail/467826.html?0#p-23b-o19-gff
            request.setService("baselineCheck");
            request.setServiceParameters(JSON.toJSONString(serviceParameters));
            ImageModerationResponse response = client.imageModerationWithOptions(request, runtime);
            if (response.getStatusCode() == 200) {
                ImageModerationResponseBody body = response.getBody();
                if (body.getCode() == 200) {
                    ImageModerationResponseBody.ImageModerationResponseBodyData data = body.getData();
                    return ImageCheckResult.builder()
                            .riskLevel(data.getRiskLevel())
                            .descriptionList(CollStreamUtil.toList(data.getResult(), ImageModerationResponseBody.ImageModerationResponseBodyDataResult::getDescription))
                            .confidenceList(CollStreamUtil.toList(data.getResult(), ImageModerationResponseBody.ImageModerationResponseBodyDataResult::getConfidence))
                            .labelList(CollStreamUtil.toList(data.getResult(), ImageModerationResponseBody.ImageModerationResponseBodyDataResult::getLabel))
                            .build();
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return ImageCheckResult.builder().build();
    }

    private OSS getOssClient(DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData tokenData, boolean isVPC) {
        //注意，此处实例化的client请尽可能重复使用，避免重复建立连接，提升检测性能。
        if (isVPC) {
            return new OSSClientBuilder().build(tokenData.ossInternalEndPoint, tokenData.getAccessKeyId(), tokenData.getAccessKeySecret(), tokenData.getSecurityToken());
        } else {
            return new OSSClientBuilder().build(tokenData.ossInternetEndPoint, tokenData.getAccessKeyId(), tokenData.getAccessKeySecret(), tokenData.getSecurityToken());
        }
    }

    public static String uploadFile(OSS ossClient, String filePath, DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData tokenData) throws Exception {
        String[] split = filePath.split("\\.");
        String objectName;
        if (split.length > 1) {
            objectName = tokenData.getFileNamePrefix() + UUID.randomUUID() + "." + split[split.length - 1];
        } else {
            objectName = tokenData.getFileNamePrefix() + UUID.randomUUID();
        }
        PutObjectRequest putObjectRequest;
        if (filePath.startsWith("http")) {

            InputStream inputStream = HttpRequest.get(filePath)
                    .timeout(30000)
                    .execute()
                    .bodyStream();
            putObjectRequest = new PutObjectRequest(tokenData.getBucketName(), objectName, inputStream);
        } else {
            putObjectRequest = new PutObjectRequest(tokenData.getBucketName(), objectName, new File(filePath));
        }
        ossClient.putObject(putObjectRequest);
        return objectName;
    }
}
